package com.naiterui.ehp.bs.pc.modules.security.service;

import com.naiterui.common.redis.RedisUtil;
import com.naiterui.ehp.bp.bo.doctor.PcUserBO;
import com.naiterui.ehp.bp.constants.CommonConstant;
import com.naiterui.ehp.bp.security.exception.BadRequestException;
import com.naiterui.ehp.bp.security.service.IPermissionService;
import com.naiterui.ehp.bp.security.utils.SecurityUtils;
import com.naiterui.ehp.bp.security.vo.FaceIdVO;
import com.naiterui.ehp.bp.utils.encypt.GengerCode;
import com.naiterui.ehp.bp.utils.lang.StringUtil;
import com.naiterui.ehp.bs.pc.common.utils.JwtUser;
import com.naiterui.ehp.bs.pc.common.utils.SMSUtil;
import com.naiterui.ehp.bs.pc.common.utils.SMSUtil.Template;
import com.naiterui.ehp.bs.pc.modules.sys.feign.IDoctorFeignClient;
import com.naiterui.ehp.bs.pc.modules.sys.mapper.UserMapper;
import com.naiterui.ehp.bs.pc.modules.sys.service.IUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Set;

@AllArgsConstructor
@Service(IPermissionService.SERVICE_NAME)
@Slf4j
public class PermissionServiceImpl implements IPermissionService {

  private final IUserService userService;
  private final UserMapper userMapper;
  @Autowired
  private IDoctorFeignClient doctorFeignClient;

  @Override
  public Boolean check(String... permissions) {
    JwtUser jwtUser = SecurityUtils.getCurrentUser();
    Set<String> permission = this.userService.getPermission(jwtUser.getId());
    return jwtUser.isAdmin() || Arrays.stream(permissions).anyMatch(permission::contains);
  }

  @Override
  public String sendSmsCode(String username) throws BadRequestException {
    if (StringUtils.isBlank(username)) {
      throw new BadRequestException("用户名为空");
    }
    // 查询用户信息
    //User user = this.userMapper.findByUsername(username);
    PcUserBO user = doctorFeignClient.getUserInfo(username);
    if (user == null) {
      throw new BadRequestException("用户不存在");
    }
    if (!StringUtil.isMobileNum(user.getPhone())) {
      throw new BadRequestException("用户手机号不正确");
    }

    String smsSendKey = this.getSmsSendKey(user.getPhone());
    String smsSendTimeKey = this.getSmsSendTimeKey(user.getPhone());
    if (RedisUtil.keyOps().existsKey(smsSendTimeKey)) {
      log.info("验证码发送过于频繁，请稍后再试,电话为phoneNum=" + user.getPhone());
      throw new BadRequestException("验证码发送过于频繁，请稍后再试!(" + StringUtil.securePhone(user.getPhone()) + ")");
    }

    // 验证码发送10分钟内不变更验证码
    String smsCode = RedisUtil.valueOps().getString(smsSendKey);
    if (StringUtils.isBlank(smsCode)) {
      smsCode = GengerCode.generateSmsCode();
    }

    SMSUtil.sendSMS(user.getPhone(), Template.USER_LOGIN_SMS_CDOE, smsCode);

    // 上次发送验证码的时间
    RedisUtil.valueOps().set(smsSendTimeKey, smsCode, 60);
    // 验证码存放10分钟
    RedisUtil.valueOps().set(smsSendKey, smsCode, 10 * 60);

    return "短信已发送至" + StringUtil.securePhone(user.getPhone()) + "，请注意查收";
  }

  @Override
  public void verifySmsCode(String username, String smsCode) {
    if (StringUtils.isAnyBlank(username, smsCode)) {
      throw new BadRequestException("用户手机号不正确");
    }
    // 登录必存在用户信息，不校验
    //User user = this.userMapper.findByUsername(username);
    PcUserBO user = doctorFeignClient.getUserInfo(username);
    if (!StringUtil.isMobileNum(user.getPhone())) {
      throw new BadRequestException("用户手机号不正确");
    }

    String smsSendKey = this.getSmsSendKey(user.getPhone());
    String smsCodeCache = RedisUtil.valueOps().getString(smsSendKey);
    if (StringUtils.equals(smsCode, smsCodeCache)) {
      RedisUtil.keyOps().delete(smsSendKey);
    } else {
      throw new BadRequestException("验证码不正确，请确认后再试");
    }
  }

  @Override
  public FaceIdVO verifyFace(String username) {
    String smsCodeCache = RedisUtil.valueOps().getString(CommonConstant.REDIS_PRE_PC + "ignore_pc_face");
    if (smsCodeCache != null) {
      return FaceIdVO.builder()
              .checkResult(true)
              .build();
    }
    PcUserBO user = doctorFeignClient.getUserFaceInfo(username, null, null);
    if (user == null) {
      throw new BadRequestException("用户不存在");
    }
    if (!user.getAuthFlag()) {
      throw new BadRequestException("未认证，请先通过APP提交资质完成认证备案");
    }
    return FaceIdVO.builder()
            .webankAppId(user.getWebankAppId())
            .orderNo(user.getOrderNo())
            .bizSeqNo(user.getBizSeqNo())
            .h5faceId(user.getH5faceId())
            .h5faceUrl(user.getH5faceUrl())
            .checkResult(user.getCheckResult())
            .optimalDomain(user.getOptimalDomain())
            .errCode(user.getErrCode())
            .build();
  }

  private String getSmsSendKey(String phone) {
    return CommonConstant.REDIS_PRE_PC + "login_send_" + phone;
  }

  private String getSmsSendTimeKey(String phone) {
    return CommonConstant.REDIS_PRE_PC + "login_send_time_" + phone;
  }

}
